package com.genntii.examManager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.genntii.examManager.common.constant.ExceptionConstant;
import com.genntii.examManager.common.constant.OrderConstant;
import com.genntii.examManager.common.exception.BaseException;
import com.genntii.examManager.common.exception.UserNotFoundException;
import com.genntii.examManager.common.result.PageResult;
import com.genntii.examManager.domain.entity.*;
import com.genntii.examManager.common.exception.CourseNotFoundException;
import com.genntii.examManager.domain.vo.UserVO;
import com.genntii.examManager.mapper.*;
import com.genntii.examManager.service.CourseRecordService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Objects;

@Service
public class CourseRecordServiceImpl extends ServiceImpl<CourseRecordMapper, CourseRecord> implements CourseRecordService {

    @Resource
    private CourseRecordMapper courseRecordMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private CourseMapper courseMapper;

    @Resource
    private ExamMapper examMapper;

    @Resource
    private PracticeMapper practiceMapper;

    @Resource
    private ExamRecordMapper examRecordMapper;

    @Resource
    private PracticeRecordMapper practiceRecordMapper;


    @Override
    public PageResult<UserVO> getStudentListByCourse(Integer pageNum, Integer pageSize, Long courseId, String sortField, String sortOrder) {
        if(sortOrder != null && !sortOrder.isBlank()) {
            if(Objects.equals(sortOrder, OrderConstant.ASC)) sortOrder = "ASC";
            else sortOrder = "DESC";
        }
        ArrayList<Long> userIds = courseRecordMapper.getUserIdsPageByCourse(courseId,(pageNum-1)*pageSize, pageSize, sortOrder, sortField);
        if(userIds.isEmpty()) throw new BaseException(ExceptionConstant.STUDENT_LIST_EMPTY_EXCEPTION);
        ArrayList<User> users = userMapper.selectUserBatch(userIds);
        ArrayList<UserVO> userVOS = new ArrayList<>();
        for (User user:users){
            LocalDateTime partInTime = courseRecordMapper.selectOne(
                            new QueryWrapper<CourseRecord>()
                                    .eq("user_id", user.getId())
                                    .eq("course_id", courseId))
                    .getCreateTime();
            UserVO userVO = UserVO.builder()
                    .id(user.getId())
                    .username(user.getUsername())
                    .nickname(user.getNickname())
                    .build();
            if(partInTime != null) userVO.setPartInTime(partInTime);
            userVOS.add(userVO);
        }
        return PageResult.build(userVOS,courseRecordMapper.getUserCountByCourse(courseId));
    }

    @Override
    @Transactional
    public void takePartInCourse(Long courseId, Long userId) {

        if (userMapper.selectById(userId) == null){
            throw new UserNotFoundException("用户不存在");
        }

        if (courseMapper.selectById(courseId) == null){
            throw new CourseNotFoundException("课程不存在");
        }

        CourseRecord courseRecord = new CourseRecord();
        courseRecord.setCourseId(courseId);
        courseRecord.setUserId(userId);
        courseRecord.setCreateTime(LocalDateTime.now());
        courseRecordMapper.insert(courseRecord);

        ArrayList<Exam> exams = examMapper.getExamAllListByCourse(courseId);
        if (exams != null){
            ArrayList<ExamRecord> examRecords = new ArrayList<>();
            for (Exam exam: exams){
                examRecords.add(ExamRecord.builder()
                        .examId(exam.getId())
                        .userId(userId)
                        .type((byte)0)
                        .build());
            }
            if(!examRecords.isEmpty()) examRecordMapper.insertBatchAll(examRecords);
        }
        ArrayList<Practice> practices = practiceMapper.getPracticeAllListByCourse(courseId);
        if (practices != null){
            ArrayList<PracticeRecord> practiceRecords = new ArrayList<>();
            for (Practice practice:practices){
                practiceRecords.add(PracticeRecord.builder()
                        .userId(userId)
                        .practiceId(practice.getId())
                        .status((byte) 0)
                        .build());
            }
            if(!practiceRecords.isEmpty()) practiceRecordMapper.insertBatchAll(practiceRecords);
        }
    }

    @Override
    public void expel(Long courseId, Long userId) {
        courseRecordMapper.expel(courseId,userId);
        ArrayList<Exam> exams = examMapper.getExamAllListByCourse(courseId);
        ArrayList<Long> examIds = new ArrayList<>();
        for (Exam exam : exams){
            examIds.add(exam.getId());
        }
        examRecordMapper.deleteByUserIdAndExamIds(userId,examIds);
        ArrayList<Practice> practices = practiceMapper.getPracticeAllListByCourse(courseId);
        ArrayList<Long> practiceIds = new ArrayList<>();
        for (Practice practice:practices){
            practiceIds.add(practice.getId());
        }
        practiceRecordMapper.deleteByUserIdAndPracticeIds(userId,practiceIds);
    }

}
